package cn.huiyunche.base.service.framework.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;

/**
 * 二维码工具类
 *
 * @author hdy
 */
public class QrCodesUtils {

    // private static final int BLACK = 0xff000000;
    // private static final int WHITE = 0xFFFFFFFF;

    /**
     * 二维码尺寸
     */
    private static final int size = 3000;
    /**
     * 二维码logo尺寸
     */
    private static final int logoSize = 600;

    /**
     * icon x坐标
     */
    private static final int icon = (size - logoSize) / 2;


    public static void drawQrCode2OutputStream(String content, String logo, HttpServletRequest request,
                                               HttpServletResponse response) {
        try {
            // 二维码显示
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            // 指定纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
            // 指定编码格式
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            // 边框留白，默认为4
            hints.put(EncodeHintType.MARGIN, 0);
            BitMatrix byteMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
            MatrixToImageConfig config = new MatrixToImageConfig(0xFF010000, MatrixToImageConfig.WHITE);
            BufferedImage image = MatrixToImageWriter.toBufferedImage(byteMatrix, config);
            File f = null;
            Graphics2D gs = image.createGraphics();
            try {
                if (StringUtils.isBlank(logo)) {
                    gs.setBackground(Color.WHITE);
                    gs.clearRect(icon, icon, logoSize, logoSize);
                    Font font = new Font(null, Font.PLAIN, 30);
                    gs.setFont(font);
                    gs.setPaint(Color.BLACK);
                    gs.drawRoundRect(icon, icon, logoSize, logoSize, 5, 5);
                    // gs.drawString(icon, x + 7, y + 28);
                } else {
                    String logoAddre = null;
                    if (!logo.startsWith("http")) {
                        logoAddre = request.getSession().getServletContext().getRealPath("/") + logo;
                    } else {
                        logoAddre = logo;
                    }
                    f = new File(logoAddre);
                    Image img = ImageIO.read(f);// 实例化一个Image对象
                    gs.drawImage(img, icon, icon, logoSize + 1, logoSize + 1, null);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                gs.dispose();
                image.flush();
                ImageIO.write(image, "png", response.getOutputStream());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成条形码
     *
     * @param content 内容
     * @param width   宽度
     * @param height  高度
     */
    public static void drawEAN13code2OutputStream(String content, int width, int height) {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getResponse();
        int codeWidth = 3 + // start guard
                (7 * 6) + // left bars
                5 + // middle guard
                (7 * 6) + // right bars
                3; // end guard
        codeWidth = Math.max(codeWidth, width);
        BufferedImage image = null;
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.EAN_13, codeWidth, height,
                    null);
            image = MatrixToImageWriter.toBufferedImage(bitMatrix);
        } catch (WriterException e) {
            e.printStackTrace();
        } finally {
            image.flush();
            try {
                ImageIO.write(image, "png", response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
